home *** CD-ROM | disk | FTP | other *** search
/ Revista CD Expert 37 / CD Expert nº 37.iso / LastCall / lastcall.exe / stuff / lastcall.dxr / 00032_Character at Bar Behavior.ls < prev    next >
Encoding:
Text File  |  2000-03-27  |  63.3 KB  |  2,291 lines

  1. property pCharCode, pLastDrinkResponse, pLastDrinkTaste, pPatronGaveTip, pDownFlag, pPerformanceInfo, pAnimating, pLabels, pActionList, pStepsInCurrentAction, pTurnOffAnim, pDrinksBeenServed, pPatience, pThrottleFrame, pThrottleTime, pPoints, pMaxPoints, pAccuracy, pDifficulty, pDrinkImpatience, pPostDrinkPatience, pPostDrinkSpacing, pPostDrinkStay, pRecipeID, pForcedRecipe, pDrinkOrder, pLastDrinkType, pCharmedPoints, pOrigRect, pOrigReg, pBigFlashRect, pRecipeName, pRecipeText, pRecipeQuick, pSoundChannel, pMyBarSlot, pWaitForVO, pLastTiming, pMouthTiming, pMouthTimingCount, pStatus, pWaitToOrderStatus, pWaitForDrinkStatus, pMouthList, pTimeApproached, pTimeOrdered, pTimeServed, pTimeLastAction, pSpr, pMouthSpr, pHandSpr, pGlassSpr, ancestor, pNoEventsDuringTest, pOrderBeckon, pOrderAntic, pOrderImpatient, pOrderLeave, pServeAntic, pServeImpatient, pServeLeave, pFrameToRecreate, pSourMilk, pLiquorGlass, pLiquorRecipe, pJuiceGlass, pPatronName
  2. global gBarTopManager, debug, gCharChildren, gRecipeWindow, gSodaDebug, gGameLevel, gMachineSpeed, gBounceInProgress, gArbusSprite, gTipPending, gQuality, gPlayerTips
  3.  
  4. on setTimeLastAction me
  5.   pTimeLastAction = now()
  6. end
  7.  
  8. on timeSinceLastAction me
  9.   return elapsedTime(pTimeLastAction)
  10. end
  11.  
  12. on timeSinceApproached me
  13.   return elapsedTime(pTimeApproached)
  14. end
  15.  
  16. on timeSinceOrdered me
  17.   return elapsedTime(pTimeOrdered)
  18. end
  19.  
  20. on timeSinceServed me
  21.   return elapsedTime(pTimeServed)
  22. end
  23.  
  24. on blankRecipeValues
  25.   pRecipeName = "No Drink"
  26. end
  27.  
  28. on removeCharacterTraces me
  29.   pCharCode = VOID
  30.   pRecipeID = 0
  31.   pForcedRecipe = 0
  32.   pStatus = #offStage
  33.   blankRecipeValues(me)
  34.   pPatronName = "No Patron"
  35.   clearRecipe(pMyBarSlot)
  36.   pActionList = []
  37.   pStepsInCurrentAction = [:]
  38.   pMouthList = [:]
  39.   pStatus = #offStage
  40.   pLastDrinkResponse = #none
  41.   pLastDrinkTaste = #none
  42.   ancestor = VOID
  43. end
  44.  
  45. on endSprite me
  46.   pSpr.rect = pOrigRect
  47.   pSpr.visible = 1
  48.   removeFromActorList(pSpr)
  49. end
  50.  
  51. on beginSprite me
  52.   global gRetrievedGame, pThrottleFrame
  53.   pThrottleFrame = 0
  54.   pSpr = sprite(me.spriteNum)
  55.   pSpr.quality = #high
  56.   pMouthSpr = sprite(me.spriteNum + 1)
  57.   pGlassSpr = sprite(me.spriteNum + 2)
  58.   pHandSpr = sprite(me.spriteNum + 3)
  59.   pOrigRect = pSpr.rect
  60.   pOrigReg = pSpr.member.regPoint
  61.   setFlashRectsInk(me)
  62.   pSoundChannel = SpriteToSoundChannel(me.spriteNum)
  63.   pMyBarSlot = SpriteToBarSlot(me.spriteNum)
  64.   removeCharacterTraces(me)
  65.   gotoFlashFrame(pSpr, "APPROACH", 1)
  66.   updateStage()
  67.   setFlashAttributes(me)
  68.   hide(me)
  69.   if pSpr.frame = 1 then
  70.     pSpr.frame = 2
  71.   end if
  72.   pOrderBeckon = currentLevel(#wo1)
  73.   pOrderAntic = currentLevel(#wo2)
  74.   pOrderImpatient = currentLevel(#wo3)
  75.   pOrderLeave = currentLevel(#wo4)
  76.   pServeAntic = currentLevel(#ws1)
  77.   pServeImpatient = currentLevel(#ws2)
  78.   pServeLeave = currentLevel(#ws3)
  79. end
  80.  
  81. on setFlashRectsInk me
  82.   global gShowFlashRects
  83.   if gShowFlashRects = 1 then
  84.     pSpr.ink = 0
  85.   else
  86.     pSpr.ink = 36
  87.   end if
  88. end
  89.  
  90. on stepFrame me
  91.   global gThrottleRate, gPauseState, gRetrievedGame
  92.   if gPauseState or gRetrievedGame or inMenuMode() then
  93.     exit
  94.   end if
  95.   if pWaitForVO then
  96.     if not soundPlaying(me) then
  97.       pWaitForVO = 0
  98.     end if
  99.     if not voidp(pMouthTiming) then
  100.       if soundPlaying(me) then
  101.         doMouthSync(me)
  102.       else
  103.         pMouthTiming = VOID
  104.         mShowMouth(me, 0)
  105.         pWaitForVO = 0
  106.         doNextAction(me)
  107.       end if
  108.     else
  109.     end if
  110.     exit
  111.   end if
  112.   if pAnimating then
  113.     thisOne = pLabels[pAnimating]
  114.     startFrame = thisOne[#start]
  115.     endFrame = thisOne[#end]
  116.     if (pSpr.frame > endFrame) or (pSpr.frame < startFrame) then
  117.       pSpr.frame = startFrame
  118.       pThrottleTime = now()
  119.     else
  120.       if pSpr.frame < endFrame then
  121.         elapsedSoFar = elapsedTime(pThrottleTime)
  122.         animSpeed = float(elapsedSoFar) / (1 + max(0, pThrottleFrame - startFrame))
  123.         if animSpeed <= gThrottleRate then
  124.           alterQuality(me, #high)
  125.           gMachineSpeed = #fast
  126.           exit
  127.         else
  128.           if animSpeed > (3 * gThrottleRate) then
  129.             alterQuality(me, gQuality)
  130.             gMachineSpeed = #verySlow
  131.           else
  132.             if animSpeed > (2 * gThrottleRate) then
  133.               alterQuality(me, gQuality)
  134.               gMachineSpeed = #slow
  135.             else
  136.               if animSpeed > (1.14999999999999991 * gThrottleRate) then
  137.                 gMachineSpeed = #medium
  138.               else
  139.                 gMachineSpeed = #medium
  140.                 alterQuality(me, #high)
  141.               end if
  142.             end if
  143.           end if
  144.         end if
  145.         pThrottleFrame = pThrottleFrame + 1
  146.         pSpr.frame = pThrottleFrame
  147.         if (pStatus = #bouncing) or inTestMode() then
  148.           gArbusSprite.frame = pThrottleFrame
  149.         end if
  150.       else
  151.         if soundPlaying(me) then
  152.           if pPerformanceInfo = 0 then
  153.             pPerformanceInfo = 1
  154.             showPerformance(me, startFrame, endFrame, "Finished Animation before sound:", thisOne[#label])
  155.           end if
  156.           exit
  157.         else
  158.           if pPerformanceInfo = 0 then
  159.             showPerformance(me, startFrame, endFrame, "Finished Animation:", thisOne[#label])
  160.           else
  161.             showPerformance(me, startFrame, endFrame, "When Sound Finished:", thisOne[#label])
  162.           end if
  163.           pPerformanceInfo = 0
  164.           doNextAction(me)
  165.         end if
  166.       end if
  167.     end if
  168.   end if
  169. end
  170.  
  171. on alterQuality me, newQuality
  172.   pSpr.quality = newQuality
  173.   gArbusSprite.quality = newQuality
  174. end
  175.  
  176. on showPerformance me, startFrame, endFrame, prompt, labels
  177.   global gThrottleRate
  178.   if not debug then
  179.     exit
  180.   end if
  181.   elapsedSoFar = elapsedTime(pThrottleTime)
  182.   frames = endFrame - startFrame + 1
  183.   achieved = float(elapsedSoFar) / frames
  184.   put prompt && labels && "for #" && pCharCode && "in position" && pMyBarSlot
  185.   rateData = float(elapsedSoFar) / frames && "ticks/frame"
  186.   target = "Target rate was" && gThrottleRate
  187.   if achieved <= (gThrottleRate + 0.14999999999999999) then
  188.     put "FAST Rate of" && rateData && "exceeded!" && target
  189.   else
  190.     if achieved <= (gThrottleRate + 0.5) then
  191.       put "GOOD Rate of" && rateData && "achieved!" && target
  192.     else
  193.       if achieved <= (gThrottleRate * 2) then
  194.         put "SLOW Rate of" && rateData && "is too slow" && target
  195.       else
  196.         put "VERY SLOW Rate of" && rateData && "really dragged." && target
  197.       end if
  198.     end if
  199.   end if
  200. end
  201.  
  202. on doMouthSync me
  203.   thisTime = sound(pSoundChannel).currentTime
  204.   startAt = pLastTiming
  205.   repeat with pLastTiming = startAt to pMouthTimingCount
  206.     if thisTime < pMouthTiming[pLastTiming] then
  207.       if (pLastTiming - 1) > 0 then
  208.         sendSprite(pMouthSpr, #mMoveMouth, getPropAt(pMouthTiming, pLastTiming))
  209.       else
  210.         sendSprite(pMouthSpr, #mMoveMouth, "nc1")
  211.       end if
  212.       exit repeat
  213.     end if
  214.   end repeat
  215. end
  216.  
  217. on mShowMouth me, flag
  218.   if voidp(flag) then
  219.     if getFrameLabel(pSpr, pSpr.frame) = "TBASE" then
  220.       flag = 1
  221.     else
  222.       flag = 0
  223.     end if
  224.   end if
  225.   sendSprite(pMouthSpr, #mAdjustPosition, getBarPositionOffset(gBarTopManager, pMyBarSlot), flag)
  226. end
  227.  
  228. on speak me, speakSound
  229.   if pNoEventsDuringTest then
  230.     exit
  231.   end if
  232.   thisSound = randomFromList(speakSound)
  233.   if debug then
  234.     put "speak" && thisSound
  235.   end if
  236.   playVO(me, thisSound, 0, VOID)
  237. end
  238.  
  239. on newRect me, newFlashRect
  240.   global gDontAdjustFlashRect, gShowArbusRects
  241.   if pNoEventsDuringTest then
  242.     exit
  243.   end if
  244.   if gShowArbusRects then
  245.     put "NEWRECT string event:" && newFlashRect
  246.   end if
  247.   newRects = value(newFlashRect)
  248.   if gShowArbusRects then
  249.     put "NEWRECT value:" && newRects
  250.   end if
  251.   if ilk(newRects, #rect) then
  252.     patronRect = newRects
  253.     arbusRect = 1
  254.   else
  255.     patronRect = newRects[1]
  256.     arbusRect = newRects[2]
  257.   end if
  258.   if ilk(patronRect, #rect) then
  259.     adjustFlashRect(me, VOID, patronRect)
  260.   end if
  261.   if ilk(arbusRect, #rect) then
  262.     adjusted = adjustFlashRect(me, VOID, arbusRect, 1)
  263.     newSpriteRect = adjusted[#rect]
  264.     trimLeft = adjusted[#left]
  265.     trimTop = adjusted[#top]
  266.     sendSprite(gArbusSprite, #adjustFlashRect, newSpriteRect, arbusRect, trimLeft, trimTop)
  267.   else
  268.     if not voidp(arbusRect) and (arbusRect = 0) then
  269.       sendSprite(gArbusSprite, #hide)
  270.     end if
  271.   end if
  272. end
  273.  
  274. on gotoLoop me, danceLoopEvent
  275.   global gCurrentSong, gThrottleRate
  276.   thisEvent = danceLoopEvent
  277.   the itemDelimiter = ","
  278.   labelName = item 1 of thisEvent
  279.   loopMax = integer(item 2 of thisEvent)
  280.   me.pDanceLoops = me.pDanceLoops + 1
  281.   if me.pDanceLoops <= loopMax then
  282.     if me.pFavoriteSong = gCurrentSong then
  283.       loopFrame = findLabel(pSpr, labelName)
  284.       if (loopFrame > 0) and (loopFrame < pSpr.frame) then
  285.         frameDiff = pSpr.frame - loopFrame
  286.         pThrottleTime = pThrottleTime + (gThrottleRate * frameDiff)
  287.         pThrottleFrame = pThrottleFrame - frameDiff
  288.       else
  289.         exit
  290.       end if
  291.     end if
  292.   end if
  293. end
  294.  
  295. on move_glass me, glassPosition
  296.   if glassPosition = "Hide" then
  297.     showHandAndGlass(me, 0)
  298.   else
  299.     glassPosition = char 1 of glassPosition
  300.     showHandAndGlass(me, 1)
  301.     nextGlass = nextGlassMember(me, glassPosition)
  302.     nextHand = nextHandMember(me, glassPosition)
  303.     if the number of member nextGlass < 1 then
  304.       put "Glass" && nextGlass && "is missing"
  305.     else
  306.       pGlassSpr.member = nextGlass
  307.     end if
  308.     if the number of member nextHand < 1 then
  309.       put "Hand" && nextHand && "is missing"
  310.     else
  311.       pHandSpr.member = nextHand
  312.     end if
  313.   end if
  314. end
  315.  
  316. on mouseDown
  317.   pDownFlag = 1
  318.   nothing()
  319. end
  320.  
  321. on mouseEnter
  322.   pDownFlag = 0
  323.   if not draggingAnything() then
  324.     thisRect = pSpr.rect
  325.     thisLabel = marker(0)
  326.     if (thisLabel <> label("card")) and (thisLabel <> label("sodaGun")) then
  327.       showToolTip(pSpr, pCharCode, point(thisRect.left + (thisRect.width / 2), min(260, thisRect.bottom - 40)), 1)
  328.     end if
  329.   end if
  330. end
  331.  
  332. on mouseLeave
  333.   pDownFlag = 0
  334.   if not draggingAnything() then
  335.     hideToolTip()
  336.   end if
  337. end
  338.  
  339. on mouseUp me
  340.   if pDownFlag then
  341.     checkIfFlashWasHit(me, pSpr)
  342.   end if
  343. end
  344.  
  345. on busy me
  346.   return pActionList <> []
  347. end
  348.  
  349. on dance me, inSound
  350.   if voidp(inSound) then
  351.     inSound = "juke_sound"
  352.   end if
  353.   if marker(0) <> label("juke") then
  354.     replaceDraggingAnything()
  355.     storeHelpPointerState()
  356.     waitCursor()
  357.     soundFX(inSound, 0, 0)
  358.     go("juke")
  359.   else
  360.     if marker(0) = label("juke") then
  361.       soundFX(inSound, 0, 0)
  362.       go("juke close")
  363.     end if
  364.   end if
  365. end
  366.  
  367. on goBase me
  368.   if statusIs(me, [#retreating, #bouncing, #offStage]) then
  369.     debugAlert("Shouldn't get to goBase with status" && pStatus)
  370.     exit
  371.   end if
  372.   forceNewAnimation(me)
  373.   playAnim(me, #base1, VOID, #stationary)
  374. end
  375.  
  376. on mRecreate me, character, patronGaveTip, charmedPoints, drinkOrder, lastDrinkType, lastDrinkResponse, lastDrinkTaste, drinksBeenServed, points, maxPoints, accuracy, status, frameNum, throttleTime, timeApproached, timeOrdered, timeServed, timeLastAction, recipeID, forcedRecipe, waitToOrderStatus, waitForDrinkStatus, animating, actionList, stepsInCurrentAction, turnOffAnim, waitForVO, lastTiming, mouthTiming, mouthTimingCount, inRect, sourMilk, liquorGlass, liquorRecipe, juiceGlass
  377.   global gImplementedCharacters
  378.   pCharCode = character
  379.   if voidp(pCharCode) then
  380.     removeCharacterTraces(me)
  381.     exit
  382.   end if
  383.   ancestor = gCharChildren[pCharCode]
  384.   pPatronName = me.pName
  385.   pPatronGaveTip = patronGaveTip
  386.   pCharmedPoints = charmedPoints
  387.   pDrinkOrder = drinkOrder
  388.   if not voidp(pDrinkOrder) then
  389.     me.pHasEverOrdered = 1
  390.   end if
  391.   pLastDrinkType = lastDrinkType
  392.   pLastDrinkResponse = lastDrinkResponse
  393.   pLastDrinkTaste = lastDrinkTaste
  394.   pDrinksBeenServed = drinksBeenServed
  395.   pPoints = points
  396.   pMaxPoints = maxPoints
  397.   pAccuracy = accuracy
  398.   pSourMilk = sourMilk
  399.   pLiquorGlass = liquorGlass
  400.   pLiquorRecipe = liquorRecipe
  401.   pJuiceGlass = juiceGlass
  402.   pStatus = status
  403.   pThrottleTime = reviseTime(throttleTime)
  404.   pTimeApproached = reviseTime(timeApproached)
  405.   pTimeOrdered = reviseTime(timeOrdered)
  406.   pTimeServed = reviseTime(timeServed)
  407.   pTimeLastAction = reviseTime(timeLastAction)
  408.   getRecipeInfo(me, recipeID, 0)
  409.   pForcedRecipe = forcedRecipe
  410.   pWaitToOrderStatus = waitToOrderStatus
  411.   pWaitForDrinkStatus = waitForDrinkStatus
  412.   pAnimating = animating
  413.   if voidp(actionList) then
  414.     pActionList = []
  415.   else
  416.     pActionList = duplicate(actionList)
  417.   end if
  418.   if voidp(stepsInCurrentAction) then
  419.     pStepsInCurrentAction = [:]
  420.   else
  421.     pStepsInCurrentAction = duplicate(stepsInCurrentAction)
  422.   end if
  423.   pTurnOffAnim = turnOffAnim
  424.   waitForVO = pWaitForVO
  425.   lastTiming = pLastTiming
  426.   mouthTiming = pMouthTiming
  427.   mouthTimingCount = pMouthTimingCount
  428.   calcPostDrinkStuff(me)
  429.   getIntoxication(me)
  430.   pMouthList = getMouthList(pCharCode)
  431.   if voidp(pMouthList) then
  432.     pMouthList = [:]
  433.   end if
  434.   oldMember = pSpr.member
  435.   pSpr.member = me.pFlashCharMember
  436.   updateStage()
  437.   unLoad(oldMember)
  438.   setFlashAttributes(me)
  439.   oldMember = pMouthSpr.member
  440.   pMouthSpr.member = me.pFlashMouthMember
  441.   preLoad(pMouthSpr.member)
  442.   updateStage()
  443.   unLoad(oldMember)
  444.   showMemoryStatus()
  445.   reg = gImplementedCharacters[pCharCode][#regPoint]
  446.   pSpr.member.regPoint = reg
  447.   pBigFlashRect = offset(pOrigRect, pOrigReg.locH - reg.locH, pOrigReg.locV - reg.locV)
  448.   pLabels = setFlashLabels(me, pSpr)
  449.   pFrameToRecreate = frameNum
  450. end
  451.  
  452. on calcPostDrinkStuff me
  453.   temp1 = currentLevel(#POSTDRINKMINPATIENCE)
  454.   temp2 = currentLevel(#POSTDRINKMAXPATIENCE)
  455.   pPostDrinkPatience = seconds(randomBetween(temp1, temp2)) * currentPatience(me)
  456.   pPostDrinkSpacing = seconds(currentLevel(#POSTDRINKANTICINTERVAL))
  457.   pPostDrinkStay = currentLevel(#postDrinkStayChance) > random(100)
  458. end
  459.  
  460. on setFlashAttributes me
  461.   pSpr.static = 1
  462.   pSpr.originMode = #topLeft
  463.   pSpr.clickMode = #boundingBox
  464.   pSpr.actionsEnabled = 1
  465.   pSpr.buttonsEnabled = 0
  466. end
  467.  
  468. on mReposition me
  469.   if voidp(pFrameToRecreate) then
  470.     hide(me)
  471.     exit
  472.   end if
  473.   fixEventTriggers(me)
  474.   gotoFlashFrame(pSpr, pFrameToRecreate, 1)
  475.   if pWaitForVO then
  476.     startAnimating(me, pAnimating)
  477.     nextStepInAnim(me)
  478.   else
  479.     if pAnimating then
  480.       pNoEventsDuringTest = 1
  481.       startAnimating(me, pAnimating)
  482.       nextStepInAnim(me)
  483.       pNoEventsDuringTest = 0
  484.     else
  485.       startFlashAnim(me, "Base1")
  486.     end if
  487.   end if
  488. end
  489.  
  490. on approach me, character
  491.   global gImplementedCharacters
  492.   pCharCode = character
  493.   ancestor = gCharChildren[pCharCode]
  494.   me.pDrinkTicket = max(0, me.pDrinkTicket - 1)
  495.   pPatronGaveTip = 0
  496.   if bouncingOrRetreating(me) then
  497.     debugAlert("Should never be approaching while being bounced or retreating")
  498.     exit
  499.   end if
  500.   pCharmedPoints = 0
  501.   blankRecipeValues(me)
  502.   pPatronName = me.pName
  503.   pDrinkOrder = VOID
  504.   pLastDrinkType = VOID
  505.   pDrinksBeenServed = 0
  506.   if inRecipeMode() then
  507.     pRecipeID = pForcedRecipe
  508.   else
  509.     pRecipeID = 0
  510.   end if
  511.   pPoints = 0
  512.   pMaxPoints = 0
  513.   pAccuracy = 0
  514.   pStatus = #approaching
  515.   pTimeApproached = now()
  516.   pWaitToOrderStatus = #new
  517.   pWaitForDrinkStatus = #new
  518.   setTimeLastAction()
  519.   resetRecipe(me)
  520.   pMouthList = getMouthList(pCharCode)
  521.   if voidp(pMouthList) then
  522.     pMouthList = [:]
  523.   end if
  524.   oldMember = pSpr.member
  525.   pSpr.member = me.pFlashCharMember
  526.   updateStage()
  527.   unLoad(oldMember)
  528.   setFlashAttributes(me)
  529.   oldMember = pMouthSpr.member
  530.   pMouthSpr.member = me.pFlashMouthMember
  531.   preLoad(pMouthSpr.member)
  532.   updateStage()
  533.   unLoad(oldMember)
  534.   if not me.pHasEverOrdered then
  535.     preLoad(member(pCharCode & "_id"))
  536.   end if
  537.   showMemoryStatus()
  538.   show(me)
  539.   reg = gImplementedCharacters[pCharCode][#regPoint]
  540.   pSpr.member.regPoint = reg
  541.   pBigFlashRect = offset(pOrigRect, pOrigReg.locH - reg.locH, pOrigReg.locV - reg.locV)
  542.   pLabels = setFlashLabels(me, pSpr)
  543.   incrementNumVisits(me)
  544.   if authoring() then
  545.     jumpToBase = inTestMode()
  546.   else
  547.     jumpToBase = 0
  548.   end if
  549.   if jumpToBase then
  550.     if me.pAlreadyCarded then
  551.       pStatus = #carded
  552.     else
  553.       pStatus = #greeted
  554.     end if
  555.     fixEventTriggers(me)
  556.     goBase(me)
  557.   else
  558.     fixEventTriggers(me)
  559.     approachAndGreet(me)
  560.   end if
  561.   pPostDrinkSpacing = seconds(currentLevel(#POSTDRINKANTICINTERVAL))
  562.   getIntoxication(me)
  563. end
  564.  
  565. on fixEventTriggers me
  566.   pNoEventsDuringTest = 1
  567.   show(me)
  568.   pSpr.rect = rect(0, 0, 1, 1)
  569.   updateStage()
  570.   gotoFrame(pSpr, 1)
  571.   updateStage()
  572.   gotoFrame(pSpr, 2)
  573.   updateStage()
  574.   pNoEventsDuringTest = 0
  575. end
  576.  
  577. on adjustFlashRect me, thisLabel, flashSubRect, CalcArbusRect
  578.   global gFlashRects, gBarTopSprite
  579.   thisChar = gFlashRects[pCharCode]
  580.   if voidp(flashSubRect) then
  581.     flashSubRect = thisChar[thisLabel]
  582.     if flashSubRect = 0 then
  583.       if (thisLabel = #base1) or (thisLabel = #tbase) then
  584.         flashSubRect = thisChar[#Bases]
  585.       else
  586.         flashSubRect = thisChar[#default]
  587.       end if
  588.     end if
  589.   end if
  590.   newSpriteRect = offset(flashSubRect, pBigFlashRect.left, pBigFlashRect.top)
  591.   specialOffset = getBarPositionOffset(gBarTopManager, pMyBarSlot)
  592.   newSpriteRect.left = newSpriteRect.left + specialOffset
  593.   newSpriteRect.right = newSpriteRect.right + specialOffset
  594.   trimLeft = 0
  595.   trimTop = 0
  596.   if newSpriteRect.left < 0 then
  597.     trimLeft = -newSpriteRect.left
  598.     newSpriteRect.left = 0
  599.   end if
  600.   if newSpriteRect.top < 0 then
  601.     trimTop = -newSpriteRect.top
  602.     newSpriteRect.top = 0
  603.   end if
  604.   if newSpriteRect.right > 640 then
  605.     newSpriteRect.right = 640
  606.   end if
  607.   barTopLimit = gBarTopSprite.top
  608.   barBottomLimit = gBarTopSprite.bottom
  609.   if newSpriteRect.bottom > barBottomLimit then
  610.     if debug then
  611.       put "Bottom of Rect should not be below bar in most cases. Potentential Problem:" && newSpriteRect.bottom
  612.     end if
  613.   else
  614.     if newSpriteRect.bottom > ((barTopLimit + barBottomLimit) / 2) then
  615.       if debug then
  616.         put "Flash Rect intersects bar half way. It may be a problem." && newSpriteRect.bottom
  617.       end if
  618.     else
  619.       if newSpriteRect.bottom > (barTopLimit + 10) then
  620.         if debug then
  621.           put "Flash Rect intersects bar no more than half way. It is probably okay." && newSpriteRect.bottom
  622.         end if
  623.       else
  624.         if newSpriteRect.bottom < barTopLimit then
  625.           if debug then
  626.             put "Bottom of Flash rect (" && newSpriteRect.bottom & ") is above the bar. I'll EXTEND it."
  627.           end if
  628.           newSpriteRect.bottom = barTopLimit
  629.         end if
  630.       end if
  631.     end if
  632.   end if
  633.   if CalcArbusRect then
  634.     return [#rect: newSpriteRect, #left: trimLeft, #top: trimTop]
  635.   else
  636.     pSpr.rect = newSpriteRect
  637.   end if
  638.   centerPt = point(newSpriteRect.width / 2.0, newSpriteRect.height / 2.0)
  639.   pSpr.viewH = flashSubRect.left + centerPt[1] + trimLeft
  640.   pSpr.viewV = flashSubRect.top + centerPt[2] + trimTop
  641. end
  642.  
  643. on showTree Msg
  644. end
  645.  
  646. on startFlashAnim me, thisLabel
  647.   alterQuality(me, #high)
  648.   showTree("      startFlashAnim")
  649.   if pStatus = #offStage then
  650.     put "exiting offstage"
  651.     exit
  652.   end if
  653.   adjustFlashRect(me, thisLabel)
  654.   thisLabel = string(thisLabel)
  655.   if findLabel(pSpr, thisLabel) then
  656.     gotoFlashFrame(pSpr, thisLabel, 1)
  657.     repeat with X = 1 to count(pLabels)
  658.       if pLabels[X][#label] = thisLabel then
  659.         foundit = 1
  660.         pThrottleFrame = pLabels[X][#start]
  661.         exit repeat
  662.       end if
  663.     end repeat
  664.     if foundit then
  665.       case pTurnOffAnim of
  666.         #stationary:
  667.           alterQuality(me, #high)
  668.           forceNewAnimation(me)
  669.         #dummy:
  670.           nothing()
  671.         otherwise:
  672.           pThrottleTime = now()
  673.           startAnimating(me, X)
  674.       end case
  675.     else
  676.       badString = "Animation" && thisLabel && "not implemented for character" && pCharCode
  677.       put "*************************** WARNING *******************" && badString
  678.       debugAlert(badString)
  679.       if thisLabel <> #base1 then
  680.         goBase(me)
  681.       end if
  682.     end if
  683.   else
  684.     debugAlert("Should never get here -- Label" && thisLabel && "not found in Flash file for character" && pCharCode)
  685.     pAnimating = 0
  686.   end if
  687. end
  688.  
  689. on doNextAction me
  690.   showTree("          DoNextAction")
  691.   if count(pStepsInCurrentAction) then
  692.     deleteAt(pStepsInCurrentAction, 1)
  693.     if count(pStepsInCurrentAction) then
  694.       nextStepInAnim(me)
  695.     else
  696.       nextAction(me)
  697.       nextAnim(me)
  698.     end if
  699.   else
  700.     if count(pActionList) then
  701.       nextAction(me)
  702.     end if
  703.     nextAnim(me)
  704.   end if
  705. end
  706.  
  707. on nextAction me
  708.   global gDrinksServedThisLevel, gTotalAccuracy, gPearlyGates
  709.   showTree("            NextAction")
  710.   pTurnOffAnim = pActionList[1][#turnOffAnim]
  711.   if count(pActionList) then
  712.     deleteAt(pActionList, 1)
  713.     stopAnimating(me)
  714.   end if
  715.   setTimeLastAction()
  716.   case pTurnOffAnim of
  717.     #bounceDone:
  718.       call(#bounced, ancestor)
  719.       showTree("#bounceDone")
  720.       gBounceInProgress = 0
  721.       characterLeft(me)
  722.     #retreatDone:
  723.       showTree("#retreatDone")
  724.       hideMyGlass(me)
  725.       characterLeft(me)
  726.     #stationary:
  727.       showTree("#stationary")
  728.       stopAnimating(me)
  729.       if othersBusy(me) = 0 then
  730.         gMachineSpeed = #fast
  731.       end if
  732.     #orderDone:
  733.       showTree("#orderDone")
  734.       if pStatus <> #ordered then
  735.         pStatus = #ordered
  736.         pTimeOrdered = now()
  737.         pWaitForDrinkStatus = #new
  738.       end if
  739.       repeat while soundPlaying(me)
  740.         checkElapsedTime()
  741.         updateStage()
  742.       end repeat
  743.       mShowMouth(me, 0)
  744.       gotoFlashFrame(pSpr, "BASE1", 1)
  745.       checkForSpecialRecipe(pRecipeID)
  746.       case me.pIntoxication of
  747.         #passedOut:
  748.           voGuide = random(10)
  749.           if voGuide >= 7 then
  750.             nothing()
  751.           else
  752.             if voGuide >= 4 then
  753.               managerVO(randomFromList(["V12", "W19", "W20"]))
  754.             else
  755.               if voGuide >= 2 then
  756.                 managerVO(randomFromList(["V10", "V11"]))
  757.               else
  758.                 managerVO(randomFromList(["V16", "v06", "v07"]))
  759.               end if
  760.             end if
  761.           end if
  762.       end case
  763.     #arriveDone:
  764.       showTree("#arriveDone")
  765.       resetNewCharacterTimer()
  766.       pTimeApproached = now()
  767.       pStatus = #greeting
  768.     #greetDone:
  769.       showTree("#greetDone")
  770.       resetNewCharacterTimer()
  771.       pTimeApproached = now()
  772.       if me.pAlreadyCarded then
  773.         if statusIs(me, [#approaching, #greeting, #greeted, #acknowledged]) then
  774.           pStatus = #carded
  775.         end if
  776.       else
  777.         pStatus = #greeted
  778.       end if
  779.     #heavenGreetDone:
  780.       gPearlyGates = 2
  781.       exit
  782.     #doneDrinking:
  783.       showTree("#doneDrinking")
  784.       updateStage()
  785.       showHandAndGlass(me, 0)
  786.       updateStage()
  787.     #doneServing:
  788.       showTree("#doneServing")
  789.       updateStage()
  790.       showHandAndGlass(me, 0)
  791.       updateStage()
  792.       goBase(me)
  793.       getIntoxication(me)
  794.       priorIntoxication = me.pIntoxication
  795.       incrementAlcohol(me, pLiquorGlass)
  796.       gDrinksServedThisLevel = gDrinksServedThisLevel + 1
  797.       gTotalAccuracy = gTotalAccuracy + pAccuracy
  798.       if pAccuracy >= currentLevel(#accVhigh) then
  799.         pLastDrinkTaste = #great
  800.       else
  801.         if pAccuracy >= currentLevel(#accHigh) then
  802.           pLastDrinkTaste = #good
  803.         else
  804.           if pAccuracy >= ((currentLevel(#accHigh) + currentLevel(#accLow)) / 2) then
  805.             pLastDrinkTaste = #okay
  806.           else
  807.             if pAccuracy >= currentLevel(#accLow) then
  808.               pLastDrinkTaste = #poor
  809.             else
  810.               pLastDrinkTaste = #awful
  811.             end if
  812.           end if
  813.         end if
  814.       end if
  815.       getIntoxication(me)
  816.       if (priorIntoxication = #passedOut) and ((pLiquorGlass > 0) or (pJuiceGlass > 2.5)) then
  817.         if pLiquorGlass > 0 then
  818.           pLastDrinkResponse = #passOut
  819.         else
  820.           if pSourMilk then
  821.             pLastDrinkResponse = #sick
  822.           else
  823.             if pJuiceGlass > 2.5 then
  824.               pLastDrinkResponse = #nonalcoholic
  825.             end if
  826.           end if
  827.         end if
  828.       else
  829.         case pLastDrinkTaste of
  830.           #great:
  831.             if pDifficulty > 5 then
  832.               pLastDrinkResponse = #PDRINKD
  833.             else
  834.               pLastDrinkResponse = #PDRINKS
  835.             end if
  836.           #good:
  837.             pLastDrinkResponse = #PDRINKS
  838.           #okay:
  839.             pLastDrinkResponse = #MDRINK
  840.           #poor:
  841.             pLastDrinkResponse = randomFromList([#NDRINKS, #NDRINKD])
  842.           #awful:
  843.             pLastDrinkResponse = #NDRINKZ
  844.         end case
  845.         if pSourMilk then
  846.           pLastDrinkResponse = #sick
  847.         else
  848.           if pLiquorGlass > (3 * pLiquorRecipe) then
  849.             pLastDrinkResponse = #puke
  850.           else
  851.             if pLiquorGlass > (2 * pLiquorRecipe) then
  852.               pLastDrinkResponse = #NDRINKZ
  853.             else
  854.               if pLiquorGlass < (pLiquorRecipe / 2.5) then
  855.                 pLastDrinkResponse = #NDRINKZ
  856.               end if
  857.             end if
  858.           end if
  859.         end if
  860.       end if
  861.       case pLastDrinkResponse of
  862.         #passOut, #sick, #puke:
  863.           playAnim(me, #passOut, VOID, #donePassingOut, VOID, 1)
  864.           gTipPending = 0
  865.         #nonalcoholic:
  866.           playAnim(me, #MDRINK, VOID, #doneNonalcoholic, VOID, 1)
  867.         #NDRINKZ:
  868.           pStatus = #served
  869.           releaseFocus(me)
  870.           playAnim(me, #NDRINKZ, #retreating, #retreatDone, VOID, 1)
  871.           gTipPending = 0
  872.         otherwise:
  873.           playAnim(me, pLastDrinkResponse, VOID, #tip, VOID, 1)
  874.       end case
  875.     #doneNonalcoholic:
  876.       showHandAndGlass(me, 0)
  877.       goBase(me)
  878.       pPatronGaveTip = 1
  879.       praiseworthyAction(me)
  880.       mSoberUp(me)
  881.       pStatus = #served
  882.       if not maxAutoAtBar(gBarTopManager) then
  883.         newCharacterEnters(#ifServed)
  884.       end if
  885.     #donePassingOut:
  886.       pStatus = #served
  887.       resetIntoxication(me)
  888.       addToPukatory(gBarTopManager, pMyBarSlot)
  889.       if pLastDrinkResponse = #sick then
  890.         managerVO(randomFromList(["v03", "w14", "w15"]))
  891.       else
  892.         if (random(3) = 1) and (gPlayerTips > 0) and (pLastDrinkResponse = #passOut) then
  893.           managerVO(randomFromList(["V01", "V02"]))
  894.           me.pBouncedPermanently = 1
  895.           regTip(-currentLevel(#maxFastTip) * 2)
  896.         else
  897.           managerVO(randomFromList(["V04", "V05", "v13", "v14", "v15"]))
  898.           regTip(-currentLevel(#maxFastTip))
  899.         end if
  900.       end if
  901.       hideMyGlass(me)
  902.       characterLeft(me)
  903.     #tip:
  904.       showTree("#tip")
  905.       showHandAndGlass(me, 0)
  906.       goBase(me)
  907.       tip(me)
  908.       pStatus = #served
  909.       if not maxAutoAtBar(gBarTopManager) then
  910.         newCharacterEnters(#ifServed)
  911.       end if
  912.   end case
  913. end
  914.  
  915. on showHandAndGlass me, flag
  916.   global gWellSprite
  917.   specialOffset = getBarPositionOffset(gBarTopManager, pMyBarSlot)
  918.   sendSprite(pGlassSpr, #mAdjustPosition, specialOffset)
  919.   sendSprite(pHandSpr, #mAdjustPosition, specialOffset)
  920.   pGlassSpr.visible = flag
  921.   pHandSpr.visible = flag
  922.   if gWellSprite.pWellSprite <> barSlotToGlassSprite(gBarTopManager, pMyBarSlot) then
  923.     showBarGlass(gBarTopManager, pMyBarSlot, not flag)
  924.   else
  925.   end if
  926. end
  927.  
  928. on soundPlaying me
  929.   return soundBusy(pSoundChannel)
  930. end
  931.  
  932. on playVO me, VOname, waitForSound, timing
  933.   pWaitForVO = waitForSound
  934.   calldebug(VOname, waitForSound, timing, me)
  935.   if voidp(VOname) then
  936.     exit
  937.   end if
  938.   pMouthTiming = timing
  939.   if listp(pMouthTiming) then
  940.     pMouthTimingCount = count(pMouthTiming)
  941.   end if
  942.   pLastTiming = 1
  943.   soundFile = VOpath(pCharCode, VOname)
  944.   if FileExists(soundFile) then
  945.     if soundPlayfile(pSoundChannel, soundFile) then
  946.       repeat while not soundBusy(pSoundChannel)
  947.       end repeat
  948.       if pWaitForVO then
  949.         gotoFlashFrame(pSpr, "Tbase", 0)
  950.         mShowMouth(me, 1)
  951.       end if
  952.     end if
  953.   else
  954.     doNextAction(me)
  955.     pWaitForVO = 0
  956.     if authoring() then
  957.       put "Missing sound file" && soundFile
  958.     end if
  959.   end if
  960. end
  961.  
  962. on playAnim me, animList, newStatusList, turnOffList, forceMatchingAction, delayAction
  963.   showTree("playAnim" && animList && newStatusList && turnOffList && forceMatchingAction)
  964.   setTimeLastAction()
  965.   if pStatus = #offStage then
  966.     exit
  967.   end if
  968.   if not listp(animList) then
  969.     animList = [animList]
  970.   end if
  971.   if not listp(newStatusList) then
  972.     newStatusList = [newStatusList]
  973.   end if
  974.   if not listp(turnOffList) then
  975.     turnOffList = [turnOffList]
  976.   end if
  977.   animCount = count(animList)
  978.   newStatusCount = count(newStatusList)
  979.   turnOffCount = count(turnOffList)
  980.   if animCount > newStatusCount then
  981.     repeat with X = newStatusCount to animCount
  982.       add(newStatusList, VOID)
  983.     end repeat
  984.   end if
  985.   if animCount > turnOffCount then
  986.     repeat with X = turnOffCount to animCount
  987.       add(turnOffList, VOID)
  988.     end repeat
  989.   end if
  990.   repeat with X = 1 to count(animList)
  991.     add(pActionList, [#action: animList[X], #turnOffAnim: turnOffList[X], #startStatus: newStatusList[X]])
  992.   end repeat
  993.   if not voidp(forceMatchingAction) then
  994.     nextAnim(me, [[#action: pLastDrinkType, #turnOffAnim: turnOffList[1], #startStatus: newStatusList[1]]], pDrinkOrder)
  995.   else
  996.     if not delayAction then
  997.       nextAnim(me)
  998.     end if
  999.   end if
  1000. end
  1001.  
  1002. on nextAnim me, action, steps
  1003.   global gPearlyGates, gUserQuitFlag
  1004.   if inMenuMode() then
  1005.     if (gPearlyGates > 0) and (pCharCode <> #BC) then
  1006.       abort()
  1007.       exit
  1008.     else
  1009.       if not gUserQuitFlag then
  1010.         abort()
  1011.         exit
  1012.       end if
  1013.     end if
  1014.   end if
  1015.   showTree("  NextAnim")
  1016.   if count(pActionList) then
  1017.     pTurnOffAnim = pActionList[1][#turnOffAnim]
  1018.     newStatus = pActionList[1][#startStatus]
  1019.     if not voidp(newStatus) then
  1020.       pStatus = newStatus
  1021.     end if
  1022.   else
  1023.     pTurnOffAnim = VOID
  1024.   end if
  1025.   if count(pActionList) = 0 then
  1026.     if (pTurnOffAnim <> #stationary) and statusNot(me, [#offStage, #approaching, #retreating, #bouncing]) then
  1027.       goBase(me)
  1028.     else
  1029.       nothing()
  1030.     end if
  1031.     exit
  1032.   end if
  1033.   if not voidp(action) then
  1034.     pActionList = action
  1035.     pStepsInCurrentAction = duplicate(steps)
  1036.     if not listp(pStepsInCurrentAction) then
  1037.       debugAlert("Invalid actions to perform for" && pActionList[1][#action] && pStepsInCurrentAction)
  1038.       exit
  1039.     end if
  1040.     nextStepInAnim(me)
  1041.     exit
  1042.   end if
  1043.   thisAction = pActionList[1][#action]
  1044.   matches = []
  1045.   lowestDifficulty = 99
  1046.   lastResort = []
  1047.   repeat with X = 1 to count(me.pCharacterActions)
  1048.     if getPropAt(me.pCharacterActions, X) = thisAction then
  1049.       stepsInThisAction = me.pCharacterActions[X][1]
  1050.       includeMe = 1
  1051.       repeat with Y = 1 to count(stepsInThisAction)
  1052.         if getPropAt(stepsInThisAction, Y) = #RID then
  1053.           thisRecipe = getRecipe(stepsInThisAction[Y])
  1054.           if listp(thisRecipe) then
  1055.             DIFFICULTY = integer(thisRecipe[#DIFFICULTY])
  1056.             MAXDRINKDIFF = currentLevel(#MAXDRINKDIFF)
  1057.             if beyondMinTips() then
  1058.               MAXDRINKDIFF = max(MAXDRINKDIFF, 5)
  1059.             end if
  1060.             if DIFFICULTY > MAXDRINKDIFF then
  1061.               if DIFFICULTY < lowestDifficulty then
  1062.                 lowestDifficulty = DIFFICULTY
  1063.                 lastResort = stepsInThisAction
  1064.               end if
  1065.               includeMe = 0
  1066.               exit repeat
  1067.             else
  1068.               includeMe = 1
  1069.             end if
  1070.             next repeat
  1071.           end if
  1072.           includeMe = 0
  1073.           exit repeat
  1074.         end if
  1075.       end repeat
  1076.       if includeMe then
  1077.         add(matches, stepsInThisAction)
  1078.       end if
  1079.     end if
  1080.   end repeat
  1081.   if (count(matches) = 0) and (lastResort <> []) then
  1082.     add(matches, lastResort)
  1083.   end if
  1084.   if count(matches) = 0 then
  1085.     debugAlert("No entry in the database for action" && thisAction && "for this character" && pCharCode)
  1086.     deleteAt(pActionList, 1)
  1087.     exit
  1088.   else
  1089.     pStepsInCurrentAction = duplicate(randomFromList(matches))
  1090.     case thisAction of
  1091.       #DRINKS, #DRINKD, #DRINKDD:
  1092.         pDrinkOrder = duplicate(pStepsInCurrentAction)
  1093.         getRecipeInfo(me, pDrinkOrder[#RID], 1)
  1094.     end case
  1095.   end if
  1096.   nextStepInAnim(me)
  1097. end
  1098.  
  1099. on setAnimationPlane me, plane
  1100.   pSpr.locZ = plane
  1101.   pMouthSpr.locZ = plane + 1
  1102. end
  1103.  
  1104. on nextStepInAnim me
  1105.   showTree("    NextStepInAnim")
  1106.   case getPropAt(pStepsInCurrentAction, 1) of
  1107.     #anim:
  1108.       animType = symbol(pStepsInCurrentAction[1])
  1109.       if debug then
  1110.         put "Next Step in Anim is" && animType
  1111.       end if
  1112.       case animType of
  1113.         #SMOVE, #sBlotto, #beckon, #pdrink:
  1114.           if pCharCode = #OG then
  1115.             newPlane = 78
  1116.           else
  1117.             newPlane = barSlotToSprite(numBarSlots()) + 1
  1118.           end if
  1119.         #retreat:
  1120.           if pCharCode = #OG then
  1121.             newPlane = 90
  1122.           else
  1123.             newPlane = barSlotToSprite(1) - 1
  1124.           end if
  1125.         #approach:
  1126.           newPlane = barSlotToSprite(1) - 1
  1127.         #bounce:
  1128.           newPlane = barSlotToSprite(1) - 1
  1129.           sendSprite(gArbusSprite, #setAnimationPlane, newPlane)
  1130.           sendSprite(gArbusSprite, #replicate, pSpr)
  1131.         #base1, #drink, #tbase, #DrinkL, #DrinkJ:
  1132.           newPlane = me.spriteNum
  1133.         otherwise:
  1134.           newPlane = barSlotToSprite(numBarSlots()) + 1
  1135.       end case
  1136.       setAnimationPlane(me, newPlane)
  1137.       startFlashAnim(me, animType)
  1138.       updateStage()
  1139.     #vo:
  1140.       setAnimationPlane(me, me.spriteNum)
  1141.       alterQuality(me, #high)
  1142.       adjustFlashRect(me, #tbase)
  1143.       showTree("      nextStepInAnim - startFlashVO")
  1144.       VOname = pStepsInCurrentAction[1]
  1145.       if debug then
  1146.         put "Reached #VO in nextAnim" && VOname
  1147.       end if
  1148.       playVO(me, VOname, 1, me.pMouthList[symbol(VOname)])
  1149.       startVOing(me)
  1150.     #RID:
  1151.       showTree("      nextStepInAnim - hit recipe ID")
  1152.       doNextAction(me)
  1153.     otherwise:
  1154.       put "Not a #rid, #vo or #anim" && getPropAt(pStepsInCurrentAction, 1)
  1155.       doNextAction(me)
  1156.   end case
  1157. end
  1158.  
  1159. on resetRecipe me
  1160.   setRecipePatronName(pMyBarSlot, pPatronName)
  1161.   setRecipeDrinkName(pMyBarSlot, pRecipeName)
  1162.   refreshRecipeWindow()
  1163. end
  1164.  
  1165. on mForceRecipe me, newRecID
  1166.   pForcedRecipe = newRecID
  1167.   takeForcedOrder(me)
  1168. end
  1169.  
  1170. on takeForcedOrder me
  1171.   if ((me.pAlreadyCarded = 1) and (pStatus = #carded)) or (pStatus = #ordered) then
  1172.     pRecipeID = pForcedRecipe
  1173.     getRecipeInfo(me, pForcedRecipe)
  1174.     pStatus = #ordered
  1175.     checkForSpecialRecipe(pForcedRecipe)
  1176.     pTimeOrdered = now()
  1177.     pWaitForDrinkStatus = #new
  1178.     thisRecipe = getRecipe(pForcedRecipe)
  1179.     if characterHasRecipe(me) then
  1180.       if statusNot(me, [#ordered, #serving, #served, #bouncing, #retreating, #offStage]) then
  1181.         newStatus = #ordering
  1182.       else
  1183.         newStatus = pStatus
  1184.       end if
  1185.       playAnim(me, pLastDrinkType, newStatus, #orderDone, pDrinkOrder)
  1186.     else
  1187.       drinkName = thisRecipe[#DisplayException]
  1188.       if drinkName = "Same" then
  1189.         drinkName = thisRecipe[#drinkName]
  1190.       end if
  1191.       case drinkName.char[1] of
  1192.         "a", "e", "i", "o", "u":
  1193.           article = "an"
  1194.         otherwise:
  1195.           article = "a"
  1196.       end case
  1197.       startText = randomFromList(["Give me", "I'll have"])
  1198.       prompt = startText && article && drinkName & "."
  1199.       resetRecipe(me)
  1200.       updateStage()
  1201.       MUIalert(prompt, "Customer Drink Order", #note, #Ok)
  1202.     end if
  1203.   end if
  1204. end
  1205.  
  1206. on randomFromWeightedActionList me, pickFrom
  1207.   matches = []
  1208.   weightList = []
  1209.   repeat with X = 1 to count(pickFrom)
  1210.     add(weightList, 0)
  1211.   end repeat
  1212.   repeat with X = 1 to count(me.pCharacterActions)
  1213.     thisAction = getPropAt(me.pCharacterActions, X)
  1214.     Match = getOne(pickFrom, thisAction)
  1215.     if Match then
  1216.       weightList[Match] = weightList[Match] + 1
  1217.     end if
  1218.   end repeat
  1219.   return randomFromWeightedList(weightList, pickFrom)
  1220. end
  1221.  
  1222. on characterHasRecipe me
  1223.   matches = []
  1224.   repeat with X = 1 to count(me.pCharacterActions)
  1225.     thisDrinkType = getPropAt(me.pCharacterActions, X)
  1226.     if getOne([#DRINKS, #DRINKD, #DRINKDD], thisDrinkType) then
  1227.       stepsInThisAction = me.pCharacterActions[X][1]
  1228.       repeat with Y = 1 to count(stepsInThisAction)
  1229.         if getPropAt(stepsInThisAction, Y) = #RID then
  1230.           if pForcedRecipe = stepsInThisAction[Y] then
  1231.             pStepsInCurrentAction = duplicate(stepsInThisAction)
  1232.             pDrinkOrder = duplicate(pStepsInCurrentAction)
  1233.             pLastDrinkType = thisDrinkType
  1234.             getRecipeInfo(me, pDrinkOrder[#RID], 0)
  1235.             return 1
  1236.           end if
  1237.         end if
  1238.       end repeat
  1239.     end if
  1240.   end repeat
  1241.   return 0
  1242. end
  1243.  
  1244. on recipes me, inSound
  1245.   global gPauseState
  1246.   if gPauseState then
  1247.     alertBeep()
  1248.     exit
  1249.   end if
  1250.   if voidp(inSound) then
  1251.     inSound = "recipe_sound"
  1252.   end if
  1253.   waitCursor()
  1254.   if recipeWindowAtLabel("quickView") then
  1255.     toggleRecipeWindow("quickView")
  1256.   else
  1257.     toggleRecipeWindow("current" & pMyBarSlot, VOID, 1)
  1258.   end if
  1259.   if draggingAnything() then
  1260.     hideCursor()
  1261.   else
  1262.     resetCursor()
  1263.   end if
  1264. end
  1265.  
  1266. on getRecipeInfo me, recipeID, refresh
  1267.   global gRecipeWindow
  1268.   pRecipeID = recipeID
  1269.   temp = getRecipe(recipeID)
  1270.   if listp(temp) then
  1271.     pDifficulty = integer(temp[#DIFFICULTY])
  1272.     pDrinkImpatience = diffFactor(pDifficulty)
  1273.   end if
  1274.   recipeInfo = createRecipe(recipeID)
  1275.   pRecipeName = recipeInfo[#name]
  1276.   setRecipeDrinkName(pMyBarSlot, pRecipeName)
  1277.   if refresh then
  1278.     refreshRecipeWindow()
  1279.   end if
  1280. end
  1281.  
  1282. on charm me, inSound
  1283.   global gPlayerGender
  1284.   if bouncingOrRetreating(me) then
  1285.     exit
  1286.   end if
  1287.   if busy(me) then
  1288.     if statusNot(me, [#greeting, #greeted, #carded, #ordered, #served]) then
  1289.       pleaseWait()
  1290.       exit
  1291.     end if
  1292.   end if
  1293.   if voidp(inSound) then
  1294.     inSound = "charm_sound"
  1295.   end if
  1296.   if me.pCharmed > me.pNumVisits then
  1297.     voList = ["F01", "F04"]
  1298.     if gPlayerGender = #male then
  1299.       add(voList, "F02")
  1300.       add(voList, "F03")
  1301.     end if
  1302.     managerVO(randomFromList(voList))
  1303.     pCharmedPoints = pCharmedPoints - 2
  1304.     exit
  1305.   end if
  1306.   case me.pCharmed of
  1307.     0:
  1308.       anim = #flatter
  1309.       points = 1
  1310.     1:
  1311.       case me.pLikesGender = gPlayerGender of
  1312.         1:
  1313.           anim = #PCharm
  1314.           points = 2
  1315.         0:
  1316.           anim = #nCharm
  1317.           points = -2
  1318.       end case
  1319.     otherwise:
  1320.       case me.pLikesGender = gPlayerGender of
  1321.         1:
  1322.           anim = #XPCHARM
  1323.           points = 3
  1324.         0:
  1325.           anim = #XNCHARM
  1326.           points = -3
  1327.       end case
  1328.   end case
  1329.   pCharmedPoints = pCharmedPoints + points
  1330.   if busy(me) then
  1331.     goBase(me)
  1332.   end if
  1333.   me.pCharmed = me.pCharmed + 1
  1334.   soundFX(inSound, 0, 0)
  1335.   playAnim(me, anim)
  1336. end
  1337.  
  1338. on forceNewAnimation me
  1339.   stopAnimating(me)
  1340.   pWaitForVO = 0
  1341.   pMouthTiming = VOID
  1342.   mShowMouth(me, 0)
  1343.   pActionList = []
  1344.   pStepsInCurrentAction = [:]
  1345. end
  1346.  
  1347. on statusNot me, statuses
  1348.   return not getOne(statuses, pStatus)
  1349. end
  1350.  
  1351. on statusIs me, statuses
  1352.   return getOne(statuses, pStatus)
  1353. end
  1354.  
  1355. on takeOrder me
  1356.   global gLastCurrent, gGaveOrderHint
  1357.   if bouncingOrRetreating(me) then
  1358.     alertBeep()
  1359.     exit
  1360.   end if
  1361.   if pStatus = #ordering then
  1362.     alertBeep()
  1363.     exit
  1364.   end if
  1365.   if statusNot(me, [#ordered, #serving, #served, #bouncing, #retreating, #offStage]) then
  1366.     newStatus = #ordering
  1367.   else
  1368.     newStatus = pStatus
  1369.   end if
  1370.   if pStatus <> #ordered then
  1371.     pTimeOrdered = now()
  1372.   end if
  1373.   stopSound(me)
  1374.   goBase(me)
  1375.   gGaveOrderHint = 1
  1376.   if voidp(pLastDrinkType) then
  1377.     case me.pIntoxication of
  1378.       #sober, #buzzed:
  1379.         pLastDrinkType = randomFromWeightedActionList(me, [#DRINKD, #DRINKS])
  1380.       #blotto:
  1381.         pLastDrinkType = randomFromWeightedActionList(me, [#DRINKD, #DRINKS])
  1382.       #passedOut:
  1383.         pLastDrinkType = randomFromList([#DRINKD, #DRINKDD])
  1384.     end case
  1385.     refreshRecipes(pMyBarSlot)
  1386.     playAnim(me, pLastDrinkType, newStatus, #orderDone)
  1387.     me.pHasEverOrdered = 1
  1388.   else
  1389.     if gLastCurrent <> pMyBarSlot then
  1390.       refreshRecipes(pMyBarSlot)
  1391.     end if
  1392.     playAnim(me, pLastDrinkType, newStatus, #orderDone, pDrinkOrder)
  1393.   end if
  1394. end
  1395.  
  1396. on order me, inSound
  1397.   global gPlayerCardWarnings, gServedUnderage
  1398.   if bouncingOrRetreating(me) then
  1399.     alertBeep()
  1400.     exit
  1401.   end if
  1402.   if voidp(inSound) then
  1403.     inSound = "order_sound"
  1404.   end if
  1405.   if inRecipeMode() then
  1406.     if not me.pAlreadyCarded then
  1407.       remindAboutID()
  1408.       exit
  1409.     end if
  1410.     if voidp(pForcedRecipe) or (pForcedRecipe = 0) then
  1411.       managerVO(randomFromList(["Y09", "Y10", "Y11", "Y12", "Y13"]))
  1412.       showRecipeAZ()
  1413.     else
  1414.       takeForcedOrder(me)
  1415.     end if
  1416.     exit
  1417.   end if
  1418.   if not me.pAlreadyCarded then
  1419.     if gGameLevel = 1 then
  1420.       remindAboutID()
  1421.     else
  1422.       if gPlayerCardWarnings < 1 then
  1423.         managerVO("E02", 1)
  1424.       else
  1425.         managerVO("E03", 1)
  1426.         managerVO("E05")
  1427.         gServedUnderage = 1
  1428.         endOfLevel()
  1429.         exit
  1430.       end if
  1431.       gPlayerCardWarnings = gPlayerCardWarnings + 1
  1432.     end if
  1433.   else
  1434.     if not me.pOver21 then
  1435.       gServedUnderage = 1
  1436.       stopPatronSounds()
  1437.       managerVO(randomFromList(["E03", "w05", "w06", "w07", "w10"]), 1, 0, 1, 1)
  1438.       endOfLevel()
  1439.     else
  1440.       if pStatus = #ordering then
  1441.         nothing()
  1442.       else
  1443.         if pStatus = #ordered then
  1444.           soundFX(inSound, 0, 0)
  1445.           takeOrder(me)
  1446.         else
  1447.           if (pStatus = #served) or (pStatus = #serving) then
  1448.             managerVO("T06")
  1449.           else
  1450.             if pStatus = #carded then
  1451.               takeOrder(me)
  1452.             else
  1453.               if pStatus = #greeting then
  1454.                 takeOrder(me)
  1455.               else
  1456.                 debugAlert("Inappropriate status" && pStatus)
  1457.               end if
  1458.             end if
  1459.           end if
  1460.         end if
  1461.       end if
  1462.     end if
  1463.   end if
  1464. end
  1465.  
  1466. on stopSound me
  1467.   sound stop pSoundChannel
  1468. end
  1469.  
  1470. on serve me, inSound, automaticServe
  1471.   global gMixingVesselsList
  1472.   if bouncingOrRetreating(me) then
  1473.     alertBeep()
  1474.     exit
  1475.   end if
  1476.   if voidp(inSound) then
  1477.     inSound = "serve_sound"
  1478.   end if
  1479.   case pStatus of
  1480.     #served:
  1481.       soundFX(inSound, 0, 0)
  1482.       managerVO(randomFromList(["T03", "I04"]))
  1483.       if not busy(me) then
  1484.         sipDrink(me)
  1485.       end if
  1486.     #serving, #ordering:
  1487.       alertBeep()
  1488.       exit
  1489.     #ordered:
  1490.       soundFX(inSound, 0, 0)
  1491.       if getBarTopGlass(gBarTopManager, pMyBarSlot) = #none then
  1492.         remindToChooseGlass(1)
  1493.         exit
  1494.       else
  1495.         if count(patronToGlass(me.spriteNum).pContents) = 0 then
  1496.           managerVO("T05")
  1497.           exit
  1498.         end if
  1499.       end if
  1500.       if (getActiveGlass() = patronToGlass(me.spriteNum)) or not automaticServe then
  1501.         emptyGlasses(1, 1)
  1502.       end if
  1503.       if timeLeftOnThisLevel() > 0 then
  1504.         gTipPending = 1
  1505.       end if
  1506.       incrementDrinks(me)
  1507.       pTimeServed = now()
  1508.       setTimeLastAction()
  1509.       pStatus = #serving
  1510.       pDrinksBeenServed = 1
  1511.       forceNewAnimation(me, #serving)
  1512.       goBase(me)
  1513.       score = scoreDrink(me)
  1514.       pPoints = score[#points]
  1515.       pMaxPoints = score[#maxPoints]
  1516.       pAccuracy = score[#accuracy]
  1517.       pDifficulty = score[#DIFFICULTY]
  1518.       pSourMilk = score[#sourMilk]
  1519.       pLiquorGlass = score[#liquorGlass]
  1520.       pLiquorRecipe = score[#liquorRecipe]
  1521.       pJuiceGlass = score[#juiceGlass]
  1522.       if pLiquorGlass > (3 * pLiquorRecipe) then
  1523.         drinkAll = 1
  1524.       else
  1525.         drinkAll = 0
  1526.       end if
  1527.       sendSprite(barSlotToGlassSprite(gBarTopManager, pMyBarSlot), #mReduceLiquid, drinkAll)
  1528.       playAnim(me, #drink, #serving, #doneServing)
  1529.       releaseFocus(me)
  1530.       calcPostDrinkStuff(me)
  1531.     otherwise:
  1532.       soundFX(inSound, 0, 0)
  1533.       if me.pAlreadyCarded then
  1534.         remindToTakeOrder()
  1535.       else
  1536.         remindAboutID()
  1537.       end if
  1538.   end case
  1539. end
  1540.  
  1541. on currentPatience me
  1542.   global gCurrentSong
  1543.   pPatience = me.pImpatience * max(0.5, min(power(currentLevel(#CHARMINFPATIENCE), pCharmedPoints), 3))
  1544.   if me.pDrinkTicket > 0 then
  1545.     pPatience = pPatience * currentLevel(#TIXINFPATIENCE)
  1546.   end if
  1547.   fav = me.pFavoriteSong
  1548.   anti = me.pHatedSong
  1549.   if gCurrentSong = fav then
  1550.     pPatience = pPatience * currentLevel(#DANCEINFPATIENCE)
  1551.   end if
  1552.   return pPatience
  1553. end
  1554.  
  1555. on beckon me
  1556.   playAnim(me, #beckon)
  1557. end
  1558.  
  1559. on timeElapsed me
  1560.   global gNoChaos, gDrinkDebug
  1561.   if gNoChaos or bouncingOrRetreating(me) then
  1562.     exit
  1563.   end if
  1564.   if busy(me) then
  1565.     exit
  1566.   end if
  1567.   beenWaiting = timeSinceLastAction(me)
  1568.   case pStatus of
  1569.     #approaching, #greeting, #bouncing, #retreating:
  1570.       exit
  1571.     #greeted, #acknowledged, #carded:
  1572.       waitToOrder(me)
  1573.     #ordering:
  1574.       nothing()
  1575.     #ordered:
  1576.       waitForDrink(me)
  1577.     #serving:
  1578.       nothing()
  1579.     #served:
  1580.       beenWaiting = timeSinceServed(me)
  1581.       if beenWaiting < pPostDrinkSpacing then
  1582.         nothing()
  1583.       else
  1584.         if busy(me) then
  1585.           nothing()
  1586.         else
  1587.           if timeSinceLastAction(me) < pPostDrinkSpacing then
  1588.             nothing()
  1589.           else
  1590.             if not pPostDrinkStay then
  1591.               retreat(me)
  1592.             else
  1593.               if beenWaiting > pPostDrinkPatience then
  1594.                 retreat(me)
  1595.               else
  1596.                 if (pMyBarSlot = 2) and ((pCharCode = #BC) or (pCharCode = #LM)) then
  1597.                   retreat(me)
  1598.                 else
  1599.                   if currentLevel(#postDrinkAnticChance) > random(100) then
  1600.                     performAntic(me)
  1601.                   else
  1602.                     if getBarTopGlass(gBarTopManager, pMyBarSlot) = #none then
  1603.                       performAntic(me)
  1604.                     else
  1605.                       sipDrink(me)
  1606.                     end if
  1607.                   end if
  1608.                 end if
  1609.               end if
  1610.             end if
  1611.           end if
  1612.         end if
  1613.       end if
  1614.     #offStage:
  1615.       nothing()
  1616.     otherwise:
  1617.       put "unknown status" && pStatus
  1618.   end case
  1619. end
  1620.  
  1621. on impatientForDrink me
  1622.   playAnim(me, randomFromList([#WDRINKS, #WDRINKD]))
  1623. end
  1624.  
  1625. on impatientToOrder me
  1626.   playAnim(me, randomFromList([#WORDERS, #WORDERD]))
  1627. end
  1628.  
  1629. on deferAction me
  1630.   if busy(me) then
  1631.     return 1
  1632.   end if
  1633.   case gMachineSpeed of
  1634.     #verySlow, #slow:
  1635.       if othersBusy(me) > 0 then
  1636.         return 1
  1637.       end if
  1638.     #medium:
  1639.       if (othersBusy(me, [#approaching, #greeting, #retreating]) > 1) or gBounceInProgress then
  1640.         return 1
  1641.       end if
  1642.     #fast:
  1643.       return 0
  1644.     otherwise:
  1645.       debugAlert("Uknown machineSpeed" && gMachineSpeed)
  1646.   end case
  1647. end
  1648.  
  1649. on waitToOrder me
  1650.   beenHere = timeSinceApproached(me)
  1651.   if deferAction(me) then
  1652.     if (beenHere > impatienceOrder(me, pOrderLeave)) and (pWaitToOrderStatus = #Impatient) then
  1653.       nothing()
  1654.     else
  1655.       exit
  1656.     end if
  1657.   end if
  1658.   if me.pIntoxication = #passedOut then
  1659.     if timeSinceLastAction(me) > pPostDrinkSpacing then
  1660.       performAntic(me)
  1661.     end if
  1662.   else
  1663.     if (beenHere > impatienceOrder(me, pOrderLeave)) and (pWaitToOrderStatus = #Impatient) then
  1664.       pWaitToOrderStatus = #disgusted
  1665.       if inRecipeMode() or (gPlayerTips = 0) then
  1666.         pWaitToOrderStatus = #Impatient
  1667.         impatientToOrder(me)
  1668.         pTimeApproached = now()
  1669.       else
  1670.         hideMyGlass(me)
  1671.         releaseFocus(me)
  1672.         playAnim(me, #WORDERZ, #retreating, #retreatDone)
  1673.       end if
  1674.     else
  1675.       if (beenHere > impatienceOrder(me, pOrderImpatient)) and (pWaitToOrderStatus = #antic) then
  1676.         pWaitToOrderStatus = #Impatient
  1677.         impatientToOrder(me)
  1678.       else
  1679.         if (beenHere > impatienceOrder(me, pOrderAntic)) and (pWaitToOrderStatus = #beckoned) then
  1680.           pWaitToOrderStatus = #antic
  1681.           case gMachineSpeed of
  1682.             #verySlow:
  1683.               anticChance = 0
  1684.             #slow:
  1685.               anticChance = currentLevel(#orderAnticChance) / 2
  1686.             otherwise:
  1687.               anticChance = currentLevel(#orderAnticChance)
  1688.           end case
  1689.           if anticChance > random(100) then
  1690.             performAntic(me)
  1691.           else
  1692.             impatientToOrder(me)
  1693.           end if
  1694.         else
  1695.           if (beenHere > impatienceOrder(me, pOrderBeckon)) and (pWaitToOrderStatus = #new) then
  1696.             pWaitToOrderStatus = #beckoned
  1697.             case gMachineSpeed of
  1698.               #verySlow:
  1699.                 exit
  1700.             end case
  1701.             beckon(me)
  1702.           end if
  1703.         end if
  1704.       end if
  1705.     end if
  1706.   end if
  1707. end
  1708.  
  1709. on hideMyGlass me
  1710. end
  1711.  
  1712. on waitForDrink me
  1713.   beenHere = timeSinceOrdered(me)
  1714.   if deferAction(me) then
  1715.     if (beenHere > impatienceDrink(me, pServeLeave)) and (pWaitForDrinkStatus = #Impatient) then
  1716.       nothing()
  1717.     else
  1718.       exit
  1719.     end if
  1720.   end if
  1721.   if me.pIntoxication = #passedOut then
  1722.     if timeSinceLastAction(me) > pPostDrinkSpacing then
  1723.       performAntic(me)
  1724.     end if
  1725.   else
  1726.     if (beenHere > impatienceDrink(me, pServeLeave)) and (pWaitForDrinkStatus = #Impatient) then
  1727.       pWaitForDrinkStatus = #disgusted
  1728.       if inRecipeMode() or (gPlayerTips = 0) then
  1729.         pWaitForDrinkStatus = #Impatient
  1730.         impatientForDrink(me)
  1731.         pTimeOrdered = now()
  1732.       else
  1733.         if mIsHoldingLiquid(barSlotToGlassSprite(gBarTopManager, pMyBarSlot)) > 0 then
  1734.           pWaitForDrinkStatus = #Impatient
  1735.           serve(me, VOID, 1)
  1736.         else
  1737.           hideMyGlass(me)
  1738.           releaseFocus(me)
  1739.           playAnim(me, #WDRINKZ, #retreating, #retreatDone)
  1740.         end if
  1741.       end if
  1742.     else
  1743.       if (beenHere > impatienceDrink(me, pServeImpatient)) and (pWaitForDrinkStatus = #antic) then
  1744.         pWaitForDrinkStatus = #Impatient
  1745.         impatientForDrink(me)
  1746.       else
  1747.         if (beenHere > impatienceDrink(me, pServeAntic)) and (pWaitForDrinkStatus = #new) then
  1748.           pWaitForDrinkStatus = #antic
  1749.           case gMachineSpeed of
  1750.             #verySlow:
  1751.               anticChance = 0
  1752.             #slow:
  1753.               anticChance = currentLevel(#serveAnticChance) / 2
  1754.             otherwise:
  1755.               anticChance = currentLevel(#serveAnticChance)
  1756.           end case
  1757.           if anticChance > random(100) then
  1758.             performAntic(me)
  1759.           else
  1760.             impatientForDrink(me)
  1761.           end if
  1762.         end if
  1763.       end if
  1764.     end if
  1765.   end if
  1766. end
  1767.  
  1768. on impatienceOrder me, someTime
  1769.   return someTime * currentPatience(me)
  1770. end
  1771.  
  1772. on impatienceDrink me, someTime
  1773.   return someTime * currentPatience(me) * pDrinkImpatience
  1774. end
  1775.  
  1776. on performAntic me
  1777.   case me.pIntoxication of
  1778.     #sober:
  1779.       playAnim(me, #ASOBER)
  1780.     #buzzed:
  1781.       playAnim(me, #ABUZZ)
  1782.     #blotto:
  1783.       playAnim(me, #ABLOTTO)
  1784.     #passedOut:
  1785.       playAnim(me, randomFromWeightedActionList(me, [#ABLOTTO, #ABUZZ]))
  1786.   end case
  1787. end
  1788.  
  1789. on hide me
  1790.   pSpr.imageEnabled = 0
  1791.   pSpr.rect = rect(0, 0, 1, 1)
  1792. end
  1793.  
  1794. on show me
  1795.   pSpr.imageEnabled = 1
  1796. end
  1797.  
  1798. on praiseworthyAction me, tip20
  1799.   thisTip = randomBetween(integer(currentLevel(#maxSlowTip)), integer(currentLevel(#MAXAVERAGETIP)))
  1800.   thisTip = min(thisTip, 20)
  1801.   if (tip20 = 1) or (random(5) = 1) then
  1802.     voList = ["v08", "v09"]
  1803.     someTip = 20
  1804.     managerVO(randomFromList(voList), 1, 0, 1)
  1805.     regTip(someTip)
  1806.   else
  1807.     voList = ["w11", "w13"]
  1808.     someTip = thisTip
  1809.     regTip(someTip)
  1810.     managerVO(randomFromList(voList))
  1811.   end if
  1812. end
  1813.  
  1814. on characterLeft me
  1815.   global gGameTips, gPearlyGates, gUserQuitFlag
  1816.   stopAnimating(me)
  1817.   hide(me)
  1818.   if the number of member (pCharCode & "_id") > 0 then
  1819.     unLoad(member(pCharCode & "_id"))
  1820.     showMemoryStatus()
  1821.   end if
  1822.   if me.pBouncedPermanently then
  1823.     if me.pOver21 then
  1824.     else
  1825.       praiseworthyAction(me, 1)
  1826.     end if
  1827.   else
  1828.     if (pWaitToOrderStatus = #disgusted) and me.pAlreadyCarded and not me.pOver21 then
  1829.       voList = ["w11", "w13"]
  1830.       if not gPearlyGates and not gUserQuitFlag then
  1831.         managerVO(randomFromList(voList))
  1832.       end if
  1833.     else
  1834.       if (pLastDrinkResponse = #sick) or (pLastDrinkResponse = #passOut) or (pLastDrinkResponse = #nonalcoholic) or (pLastDrinkResponse = #puke) then
  1835.         nothing()
  1836.       else
  1837.         if (pWaitToOrderStatus = #disgusted) or (pWaitForDrinkStatus = #disgusted) or (pLastDrinkTaste = #awful) then
  1838.           voList = ["L01", "L02", "L03"]
  1839.           if gGameTips then
  1840.             add(voList, "u14")
  1841.           end if
  1842.           if not gPearlyGates and not gUserQuitFlag then
  1843.             if gGameLevel < 3 then
  1844.               managerVO(randomFromList(voList))
  1845.             end if
  1846.           end if
  1847.           resetForcedCharacterTimer()
  1848.         end if
  1849.       end if
  1850.     end if
  1851.   end if
  1852.   releaseFocus(me)
  1853.   removeCharacterTraces(me)
  1854.   removeBarTopCharacter(gBarTopManager, pMyBarSlot)
  1855.   releaseFocus(me)
  1856.   if (pPatronGaveTip and not maxAutoAtBar(gBarTopManager)) or (numberAtBar(gBarTopManager) = 0) then
  1857.     if not inTestMode() then
  1858.       newCharacterEnters(#ifServed)
  1859.     end if
  1860.   end if
  1861. end
  1862.  
  1863. on stopAnimating me
  1864.   showTree("stopAnimating")
  1865.   pAnimating = 0
  1866.   mShowMouth(me)
  1867.   showHandAndGlass(me, 0)
  1868.   stopSound(me)
  1869.   removeFromActorList(pSpr)
  1870. end
  1871.  
  1872. on startAnimating me, X
  1873.   showTree("        startAnimating")
  1874.   pAnimating = X
  1875.   addToActorList(pSpr)
  1876. end
  1877.  
  1878. on startVOing me
  1879.   showTree("        startVOing")
  1880.   addToActorList(pSpr)
  1881. end
  1882.  
  1883. on retreat me
  1884.   hideMyGlass(me)
  1885.   releaseFocus(me)
  1886.   playAnim(me, #retreat, #retreating, #retreatDone)
  1887. end
  1888.  
  1889. on releaseFocus me
  1890.   if pMyBarSlot = getActiveSlot(gBarTopManager) then
  1891.     makePatronActive()
  1892.   end if
  1893. end
  1894.  
  1895. on retreating me
  1896.   return pStatus = #retreating
  1897. end
  1898.  
  1899. on bouncingOrRetreating me
  1900.   return statusIs(me, [#retreating, #bouncing])
  1901. end
  1902.  
  1903. on toughLove me, inSound
  1904.   if gBounceInProgress then
  1905.     alertBeep()
  1906.     pleaseWait("MO3")
  1907.     exit
  1908.   end if
  1909.   if voidp(inSound) then
  1910.     inSound = "bounce_soundold"
  1911.   end if
  1912.   case pStatus of
  1913.     #offStage, #greeting, #approaching:
  1914.       alertBeep()
  1915.       pleaseWait("M02")
  1916.     #retreating:
  1917.       alertBeep()
  1918.       exit
  1919.     #bouncing:
  1920.       debugAlert("Should never get here - Should be tracked to bouncing up above.")
  1921.     #greeted, #acknowledged, #carded, #ordering, #ordered, #served, #serving:
  1922.       soundFX(inSound, 0, 0)
  1923.       goBase(me)
  1924.       forceNewAnimation(me, #bouncing)
  1925.       gBounceInProgress = 1
  1926.       releaseFocus(me)
  1927.       playAnim(me, #bounce, #bouncing, #bounceDone)
  1928.     otherwise:
  1929.       alertBeep()
  1930.       put "Unknown status while trying to bounce"
  1931.   end case
  1932. end
  1933.  
  1934. on findClosestMatch me
  1935.   global gRecipes, gFindClosest
  1936.   if inRecipeMode() and gFindClosest then
  1937.     waitCursor()
  1938.     bestAccuracy = 0
  1939.     bestMatchAccuracy = 0
  1940.     bestPoints = 0
  1941.     bestMatchPoints = 0
  1942.     repeat with X = 1 to count(gRecipes)
  1943.       matchRecipe = gRecipes[X]
  1944.       scoring = rateDrink(me, matchRecipe)
  1945.       if scoring[#accuracy] > bestAccuracy then
  1946.         bestAccuracy = scoring[#accuracy]
  1947.         bestMatchAccuracy = matchRecipe
  1948.       end if
  1949.       if scoring[#points] > bestPoints then
  1950.         bestPoints = scoring[#points]
  1951.         bestMatchPoints = matchRecipe
  1952.       end if
  1953.     end repeat
  1954.     resetCursor()
  1955.     MUIalert("Most accurate match" && bestAccuracy && bestMatchAccuracy[#drinkName])
  1956.     MUIalert("Most points scored" && bestPoints && bestMatchPoints[#drinkName])
  1957.   end if
  1958. end
  1959.  
  1960. on scoreDrink me
  1961.   clearDrinkDisplay()
  1962.   findClosestMatch(me)
  1963.   matchRecipe = getRecipe(pRecipeID)
  1964.   return rateDrink(me, matchRecipe)
  1965. end
  1966.  
  1967. on rateDrink me, matchRecipe
  1968.   global gRecipes
  1969.   points = 0
  1970.   maxPoints = 0
  1971.   DIFFICULTY = 0
  1972.   accuracy = 0
  1973.   liquorRecipe = 0
  1974.   agitated = 0
  1975.   carbonated = 0
  1976.   iceAdded = 0
  1977.   beforeIce = 0
  1978.   loseAgitatePoints = 0
  1979.   loseIcePoints = 0
  1980.   myContents = patronToGlass(me.spriteNum).pContents
  1981.   liquorGlass = calcLiquorContents(myContents)
  1982.   juiceGlass = calcWimpyContents(myContents)
  1983.   reportDrink("Eval. Rec ID:" && integer(pRecipeID) & "," && matchRecipe[#drinkName] & ", Diff.:" && integer(matchRecipe[#DIFFICULTY]))
  1984.   repeat with X = 1 to count(matchRecipe)
  1985.     thisProp = getPropAt(matchRecipe, X)
  1986.     thisValue = matchRecipe[X]
  1987.     case thisProp of
  1988.       #RECID:
  1989.         recipeID = integer(thisValue)
  1990.       #drinkName:
  1991.         drinkName = thisValue
  1992.       #DIFFICULTY:
  1993.         DIFFICULTY = integer(thisValue)
  1994.       #NOTES:
  1995.         nothing()
  1996.       #ingredients:
  1997.         repeat with thisIng in thisValue
  1998.           maxPoints = maxPoints + thisIng[#p]
  1999.           reportDrink(getNameByID(thisIng[#INGID]) && "worth" && thisIng[#p] && "points for quantity" && thisIng[#q])
  2000.           checkForLiquor = findingredientbyid(thisIng[#INGID])
  2001.           if checkForLiquor = #beer then
  2002.             liquorRecipe = liquorRecipe + (thisIng[#q] * 2.0)
  2003.             next repeat
  2004.           end if
  2005.           if isLiquor(checkForLiquor) then
  2006.             liquorRecipe = liquorRecipe + thisIng[#q]
  2007.           end if
  2008.         end repeat
  2009.       #SPECIAL_CASE, #DisplayException:
  2010.         nothing()
  2011.       otherwise:
  2012.         put "Unknown data type in recipes" && thisProp
  2013.     end case
  2014.   end repeat
  2015.   reportDrink("Evaluating" && myContents)
  2016.   repeat with X = 1 to count(myContents)
  2017.     ingredient = getPropAt(myContents, X)
  2018.     ingInfo = findIngredientInRecipe(matchRecipe, ingredient)
  2019.     altInfo = isAlternateInRecipe(matchRecipe, ingredient)
  2020.     case ingredient of
  2021.       #Muddle, #coat_and_rim:
  2022.         put "Muddle and Coat & Rim not implemented"
  2023.       #blend, #shake, #stir, #shaker, #blender, #mixingGlass:
  2024.         Quantity = 1
  2025.         points = mEvaluateIfPrimaryOrSubstituteAvoidDupes(me, matchRecipe, ingredient, "vessel", points, myContents)
  2026.         if getOne([#shake, #blend], ingredient) and carbonated then
  2027.           agitated = 1
  2028.           if not voidp(ingInfo) then
  2029.             loseAgitatePoints = ingInfo[#p]
  2030.           end if
  2031.         end if
  2032.       #iceNonGlass:
  2033.         Quantity = myContents[X]
  2034.         if voidp(ingInfo) then
  2035.           reportDrink("Void icenonglass")
  2036.           Quantity = 1.0
  2037.         else
  2038.           points = points + ingInfo[#p]
  2039.           reportDrink(ingInfo[#p] && "points for correct" && ingredient)
  2040.         end if
  2041.       #olive, #lemonWedge, #orangeWedge, #limeWedge, #cherry, #limetwist, #lemontwist:
  2042.         points = mEvaluateIfPrimaryOrSubstitute(me, matchRecipe, ingredient, "garnish", points)
  2043.       otherwise:
  2044.         if isCarbonated(ingredient) then
  2045.           carbonated = 1
  2046.         end if
  2047.         if ingredient = #ice then
  2048.           if not voidp(ingInfo) then
  2049.             loseIcePoints = ingInfo[#p]
  2050.           end if
  2051.           iceAdded = 1
  2052.         else
  2053.           if iceAdded = 0 then
  2054.             beforeIce = 1
  2055.           end if
  2056.         end if
  2057.         Quantity = myContents[X]
  2058.         if voidp(ingInfo) then
  2059.           points = points - (3 * Quantity)
  2060.           reportDrink("Lost" && 3 * Quantity && "points for wrong ingredient" && getname(ingredient))
  2061.         else
  2062.           if Quantity = 0 then
  2063.             percentCorrect = 0
  2064.           else
  2065.             percentCorrect = 1.0 - (abs(ingInfo[#q] - Quantity) / float(Quantity))
  2066.           end if
  2067.           points = points + (ingInfo[#p] * percentCorrect)
  2068.           reportDrink(ingInfo[#p] * percentCorrect && "points for" && percentCorrect & "% correct" && getname(ingredient))
  2069.         end if
  2070.     end case
  2071.   end repeat
  2072.   glassType = getBarTopGlass(gBarTopManager, pMyBarSlot)
  2073.   if glassType <> #beer then
  2074.     points = mEvaluateIfPrimaryOrSubstitute(me, matchRecipe, glassType, "glass", points)
  2075.   end if
  2076.   points = max(0, points)
  2077.   if maxPoints = 0 then
  2078.     reportDrink("Pointless recipe" && recipeID)
  2079.     accuracy = 0
  2080.   else
  2081.     accuracy = min(1.0, float(points) / maxPoints)
  2082.   end if
  2083.   reportDrink("Accuracy" && accuracy && "(" & points && "out of" && maxPoints & ")")
  2084.   if authoring() and debug then
  2085.     MUIalert("Drink mixing accuracy" && accuracy && "(" & points && "out of" && maxPoints & ")")
  2086.   end if
  2087.   sourMilk = milkWillSour(myContents, matchRecipe)
  2088.   if agitated then
  2089.     if loseAgitatePoints = 0 then
  2090.       loseAgitatePoints = 5
  2091.     end if
  2092.     if pRecipeID = 96 then
  2093.       reportDrink("Agitating carbonated liquid okay for Sweet Tart")
  2094.     else
  2095.       points = points - loseAgitatePoints
  2096.       reportDrink("Losing points for agitating carbonated liquid" && loseAgitatePoints)
  2097.     end if
  2098.   end if
  2099.   if beforeIce and iceAdded then
  2100.     if loseIcePoints = 0 then
  2101.       loseIcePoints = 5
  2102.     end if
  2103.     reportDrink("Losing points for adding ice after contents" && loseIcePoints)
  2104.     points = points - loseIcePoints
  2105.   end if
  2106.   scoring = [#points: points, #maxPoints: maxPoints, #accuracy: accuracy, #DIFFICULTY: DIFFICULTY, #sourMilk: sourMilk, #liquorGlass: liquorGlass, #liquorRecipe: liquorRecipe, #juiceGlass: juiceGlass]
  2107.   if debug then
  2108.     put "Scoring" && scoring
  2109.   end if
  2110.   return scoring
  2111. end
  2112.  
  2113. on mEvaluateIfPrimaryOrSubstitute me, matchRecipe, ingredient, textName, points
  2114.   global gIngredients
  2115.   ingInfo = findIngredientInRecipe(matchRecipe, ingredient)
  2116.   if voidp(ingInfo) then
  2117.     substitutesFor = isAlternateInRecipe(matchRecipe, gIngredients[ingredient][#INGID])
  2118.     if count(substitutesFor) then
  2119.       repeat with substituteGlassOrGarnish in substitutesFor
  2120.         ingInfo = findIngredientInRecipe(matchRecipe, substituteGlassOrGarnish[#ingName])
  2121.         if not voidp(ingInfo) then
  2122.           partialPoints = ingInfo[#p] * substituteGlassOrGarnish[#pA]
  2123.           reportDrink("Earned" && partialPoints && "points for substitute" && textName & ":" && ingredient && "instead of" && substituteGlassOrGarnish[#ingName])
  2124.           points = points + partialPoints
  2125.           exit repeat
  2126.         end if
  2127.       end repeat
  2128.     else
  2129.       reportDrink("Abysmal" && textName & ". No points for" && ingredient)
  2130.     end if
  2131.   else
  2132.     reportDrink("Scored full points" && ingInfo[#p] && "for correct" && textName)
  2133.     points = points + ingInfo[#p]
  2134.   end if
  2135.   return points
  2136. end
  2137.  
  2138. on mEvaluateIfPrimaryOrSubstituteAvoidDupes me, matchRecipe, ingredient, textName, points, myContents, correctQuantity
  2139.   global gIngredients
  2140.   ingInfo = findIngredientInRecipe(matchRecipe, ingredient)
  2141.   if voidp(ingInfo) then
  2142.     reportDrink("Lost 2 points for wrong action" && ingredient)
  2143.   else
  2144.     reportDrink("Scored points" && ingInfo[#p] && "for correct" && textName)
  2145.     points = points + ingInfo[#p]
  2146.   end if
  2147.   return points
  2148. end
  2149.  
  2150. on secondsWaitingForDrink me
  2151.   return ticksToSeconds(pTimeServed - pTimeOrdered)
  2152. end
  2153.  
  2154. on tip me
  2155.   pPatronGaveTip = 1
  2156.   pay = getDollarScore(secondsWaitingForDrink(me), pAccuracy, currentPatience(me), pDifficulty)
  2157.   cents = pay - integer(pay / 100.0 * 100)
  2158.   tens = floor(cents * 10)
  2159.   pennies = integer(cents * 100) mod 10
  2160.   if (pennies <> 0) and (pennies <> 5) then
  2161.     cents = (tens * 10) + getAt([0, 5], random(2))
  2162.     pay = floor(pay) + (float(cents) / 100.0)
  2163.   end if
  2164.   pay = pay + (min(1, me.pDrinkTicket) * currentLevel(#TIXINFCOST))
  2165.   regTip(pay)
  2166. end
  2167.  
  2168. on sipDrink me
  2169.   if getBarTopGlass(gBarTopManager, pMyBarSlot) <> #none then
  2170.     sendSprite(barSlotToGlassSprite(gBarTopManager, pMyBarSlot), #mReduceLiquid)
  2171.     playAnim(me, #drink, VOID, #doneDrinking)
  2172.   end if
  2173. end
  2174.  
  2175. on passOut me
  2176.   playAnim(me, #passOut)
  2177. end
  2178.  
  2179. on getPropertyDescriptionList me
  2180.   characterList = [#AT, #BC, #CG, #EM, #GR, #JF, #JS, #KY, #LC, #LG, #LM, #LN, #OG, #RN, #SC, #SM, #TF, #TJ, #VH, #XF]
  2181.   return [#pCharCode: [#default: #OG, #comment: "Character Code", #range: characterList, #format: #symbol]]
  2182. end
  2183.  
  2184. on drinkTicket me, inSound
  2185.   global gPlayerDrinkTickets, gPlayerTips
  2186.   if bouncingOrRetreating(me) then
  2187.     alertBeep()
  2188.     exit
  2189.   end if
  2190.   if voidp(inSound) then
  2191.     inSound = "ticket_sound"
  2192.   end if
  2193.   maxTickets = sumGameLevels(#TIX)
  2194.   costPerTicket = currentLevel(#TIXCOST)
  2195.   nextTicket = gPlayerDrinkTickets + 1
  2196.   playIt = 0
  2197.   if nextTicket > maxTickets then
  2198.     if gPlayerTips >= costPerTicket then
  2199.       regTip(-costPerTicket, 1)
  2200.       playIt = 1
  2201.     else
  2202.       soundFX2("bad_drink", 0, 0)
  2203.     end if
  2204.   else
  2205.     if nextTicket = maxTickets then
  2206.       ticketWarning = #lastOne
  2207.       playIt = 1
  2208.     else
  2209.       if nextTicket = (maxTickets - 1) then
  2210.         ticketWarning = #freebies
  2211.       end if
  2212.       playIt = 1
  2213.     end if
  2214.   end if
  2215.   if playIt then
  2216.     if busy(me) then
  2217.       if statusIs(me, [#greeting, #greeted, #carded, #ordered, #served]) then
  2218.         goBase(me)
  2219.       else
  2220.         pleaseWait()
  2221.         exit
  2222.       end if
  2223.     end if
  2224.     me.pDrinkTicket = me.pDrinkTicket + 1
  2225.     gPlayerDrinkTickets = gPlayerDrinkTickets + 1
  2226.     soundFX(inSound, 0, 1)
  2227.     case ticketWarning of
  2228.       #lastOne:
  2229.         managerVO("N03")
  2230.       #freebies:
  2231.         managerVO("N02")
  2232.     end case
  2233.     goBase(me)
  2234.     playAnim(me, #TICKET)
  2235.   end if
  2236. end
  2237.  
  2238. on card me, inSound
  2239.   global gGaveIDcardHint
  2240.   if label("card") = marker(0) then
  2241.     returnToBar()
  2242.     exit
  2243.   end if
  2244.   if bouncingOrRetreating(me) then
  2245.     alertBeep()
  2246.     exit
  2247.   end if
  2248.   if voidp(inSound) then
  2249.     inSound = "card_sound"
  2250.   end if
  2251.   if me.pAlreadyCarded and statusIs(me, [#carded, #ordered, #ordering, #served, #serving]) then
  2252.     managerVO("E07")
  2253.   end if
  2254.   case pStatus of
  2255.     #approaching, #greeting, #greeted, #acknowledged, #carded, #ordering, #ordered, #served, #serving:
  2256.       replaceDraggingAnything()
  2257.       soundFX(inSound, 0, 0)
  2258.       gGaveIDcardHint = 1
  2259.       waitCursor()
  2260.       dismissToolTip(1)
  2261.       go("Card")
  2262.       if not me.pAlreadyCarded or statusIs(me, [#approaching, #greeting, #greeted, #acknowledged]) then
  2263.         me.pAlreadyCarded = 1
  2264.         pStatus = #carded
  2265.       end if
  2266.     #retreating, #bouncing:
  2267.       alertBeep()
  2268.       exit
  2269.   end case
  2270. end
  2271.  
  2272. on othersBusy me, statuses
  2273.   global gCharacterSprites
  2274.   numBusy = 0
  2275.   repeat with X in gCharacterSprites
  2276.     if X = me.spriteNum then
  2277.       next repeat
  2278.     end if
  2279.     if sendSprite(X, #busy) then
  2280.       if voidp(statuses) then
  2281.         numBusy = numBusy + 1
  2282.         next repeat
  2283.       end if
  2284.       if sendSprite(X, #statusIs, statuses) then
  2285.         numBusy = numBusy + 1
  2286.       end if
  2287.     end if
  2288.   end repeat
  2289.   return numBusy
  2290. end
  2291.